<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>NYC出租车智能定价策略分析大屏</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
            font-family: 'Microsoft YaHei', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: #ffffff;
            overflow: hidden;
            height: 100vh;
        }

        .dashboard {
            width: 100vw;
            height: 100vh;
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: 80px repeat(3, 1fr);
            gap: 8px;
            padding: 8px;
        }

        .header {
            grid-column: 1 / -1;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
            backdrop-filter: blur(15px);
            border: 1px solid rgba(255, 255, 255, 0.2);
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        }

        .header h1 {
            font-size: 2.2em;
            font-weight: 600;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
            background: linear-gradient(45deg, #64b5f6, #42a5f5, #2196f3);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }

        .chart-container {
            background: rgba(255, 255, 255, 0.08);
            border-radius: 12px;
            padding: 12px;
            backdrop-filter: blur(15px);
            border: 1px solid rgba(255, 255, 255, 0.15);
            box-shadow: 0 6px 25px rgba(0, 0, 0, 0.2);
            position: relative;
            overflow: hidden;
            transition: all 0.3s ease;
        }

        .chart-container:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
        }

        .chart-container::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 3px;
            background: linear-gradient(90deg, #64b5f6, #42a5f5, #2196f3, #1976d2);
            border-radius: 12px 12px 0 0;
        }

        .chart-title {
            font-size: 1.1em;
            font-weight: 600;
            margin-bottom: 8px;
            text-align: center;
            color: #e3f2fd;
            text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
        }

        .chart {
            width: 100%;
            height: calc(100% - 35px);
            min-height: 200px;
        }

        .large-chart {
            grid-column: span 2;
        }

        .stats-container {
            display: grid;
            grid-template-columns: 1fr 1fr;
            grid-template-rows: 1fr 1fr;
            gap: 8px;
            height: 100%;
        }

        .stat-item {
            background: rgba(255, 255, 255, 0.1);
            border-radius: 8px;
            padding: 12px;
            text-align: center;
            border: 1px solid rgba(255, 255, 255, 0.2);
            transition: all 0.3s ease;
        }

        .stat-item:hover {
            background: rgba(255, 255, 255, 0.15);
            transform: scale(1.02);
        }

        .stat-value {
            font-size: 1.6em;
            font-weight: 700;
            color: #64b5f6;
            margin-bottom: 4px;
            text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
        }

        .stat-label {
            font-size: 0.85em;
            color: #b3e5fc;
            font-weight: 500;
        }

        .loading {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100%;
            font-size: 1.1em;
            color: #90caf9;
        }

        @keyframes pulse {
            0%, 100% { opacity: 0.8; }
            50% { opacity: 1; }
        }

        .loading::after {
            content: '...';
            animation: pulse 1.5s infinite;
        }
    </style>
</head>
<body>
<div class="dashboard">
    <div class="header">
        <h1>🚕 NYC出租车智能定价策略分析大屏</h1>
    </div>

    <div class="chart-container large-chart">
        <div class="chart-title">📊 多维度定价分析</div>
        <div id="multiDimensionalChart" class="chart">
            <div class="loading">正在加载数据</div>
        </div>
    </div>

    <div class="chart-container">
        <div class="chart-title">📈 定价效率趋势</div>
        <div id="efficiencyChart" class="chart">
            <div class="loading">正在加载数据</div>
        </div>
    </div>

    <div class="chart-container">
        <div class="chart-title">💰 关键指标</div>
        <div class="stats-container">
            <div class="stat-item">
                <div class="stat-value" id="avgFare">$0.00</div>
                <div class="stat-label">平均费用</div>
            </div>
            <div class="stat-item">
                <div class="stat-value" id="avgTipRate">0.0%</div>
                <div class="stat-label">平均小费率</div>
            </div>
            <div class="stat-item">
                <div class="stat-value" id="surgeMultiplier">0.0x</div>
                <div class="stat-label">激增倍数</div>
            </div>
            <div class="stat-item">
                <div class="stat-value" id="efficiency">0.0%</div>
                <div class="stat-label">定价效率</div>
            </div>
        </div>
    </div>

    <div class="chart-container">
        <div class="chart-title">🎯 条件定价策略</div>
        <div id="conditionalChart" class="chart">
            <div class="loading">正在加载数据</div>
        </div>
    </div>

    <div class="chart-container">
        <div class="chart-title">⏰ 时间窗口分析</div>
        <div id="timeWindowChart" class="chart">
            <div class="loading">正在加载数据</div>
        </div>
    </div>

    <div class="chart-container">
        <div class="chart-title">🏗️ 分层聚合结构</div>
        <div id="hierarchicalChart" class="chart">
            <div class="loading">正在加载数据</div>
        </div>
    </div>

    <div class="chart-container large-chart">
        <div class="chart-title">🔄 嵌套聚合效果</div>
        <div id="nestedChart" class="chart">
            <div class="loading">正在加载数据</div>
        </div>
    </div>
</div>

<script>
    // 全局变量
    let charts = {};
    let animationId;

    // 数据生成器
    class DataGenerator {
        static generateMultiDimensionalData() {
            const timePeriods = ['早高峰', '平峰', '晚高峰', '夜间', '深夜'];
            const distanceCategories = ['短途', '中途', '长途', '超长途'];
            const data = [];

            timePeriods.forEach((period, i) => {
                distanceCategories.forEach((distance, j) => {
                    data.push([
                        i, j,
                        Math.round((Math.random() * 25 + 10 + i * 3 + j * 2) * 100) / 100
                    ]);
                });
            });

            return { data, timePeriods, distanceCategories };
        }

        static generateEfficiencyData() {
            return Array.from({ length: 24 }, (_, i) => ({
                hour: i,
                efficiency: Math.round((Math.sin(i * Math.PI / 12) * 15 + 75 + Math.random() * 10) * 10) / 10,
                surge: Math.round((Math.sin((i - 6) * Math.PI / 12) * 0.3 + 1.2 + Math.random() * 0.2) * 100) / 100
            }));
        }

        static generateConditionalData() {
            return [
                { name: '高峰高价值', value: 28.5, count: 1250 },
                { name: '竞争长途', value: 45.2, count: 890 },
                { name: '高端拥堵', value: 35.8, count: 650 },
                { name: '工作日经济', value: 15.3, count: 2100 },
                { name: '周末休闲', value: 22.1, count: 1580 }
            ];
        }

        static generateTimeWindowData() {
            return Array.from({ length: 12 }, (_, i) => ({
                period: `${i * 2}:00-${(i + 1) * 2}:00`,
                hourWindow: Math.round((Math.random() * 15 + 15) * 100) / 100,
                periodWindow: Math.round((Math.random() * 20 + 20) * 100) / 100,
                dayTypeWindow: Math.round((Math.random() * 18 + 18) * 100) / 100
            }));
        }

        static generateHierarchicalData() {
            return [
                { name: '全局', value: 100, itemStyle: { color: '#64b5f6' } },
                { name: '时间类型', value: 45, itemStyle: { color: '#42a5f5' } },
                { name: '距离定价', value: 35, itemStyle: { color: '#2196f3' } },
                { name: '客户类型', value: 25, itemStyle: { color: '#1976d2' } },
                { name: '路线分析', value: 20, itemStyle: { color: '#1565c0' } }
            ];
        }

        static generateNestedData() {
            return {
                route: { count: 1500, avgFare: 22.5, efficiency: 85 },
                timeCustomer: { count: 1200, avgFare: 26.8, efficiency: 78 },
                pricing: { count: 800, avgFare: 31.2, efficiency: 89 }
            };
        }
    }

    // 图表初始化器
    class ChartInitializer {
        static initMultiDimensionalChart() {
            const container = document.getElementById('multiDimensionalChart');
            if (!container) return;

            const chart = echarts.init(container);
            const { data, timePeriods, distanceCategories } = DataGenerator.generateMultiDimensionalData();

            const option = {
                tooltip: {
                    position: 'top',
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    borderColor: '#64b5f6',
                    textStyle: { color: '#fff' },
                    formatter: function(params) {
                        return `${timePeriods[params.data[0]]} - ${distanceCategories[params.data[1]]}<br/>平均费用: $${params.data[2]}`;
                    }
                },
                grid: {
                    left: '10%',
                    right: '10%',
                    top: '10%',
                    bottom: '15%'
                },
                xAxis: {
                    type: 'category',
                    data: timePeriods,
                    splitArea: { show: true },
                    axisLabel: { color: '#e3f2fd', fontSize: 11 },
                    axisLine: { lineStyle: { color: '#64b5f6' } }
                },
                yAxis: {
                    type: 'category',
                    data: distanceCategories,
                    splitArea: { show: true },
                    axisLabel: { color: '#e3f2fd', fontSize: 11 },
                    axisLine: { lineStyle: { color: '#64b5f6' } }
                },
                visualMap: {
                    min: 10,
                    max: 50,
                    calculable: true,
                    orient: 'horizontal',
                    left: 'center',
                    bottom: '5%',
                    textStyle: { color: '#e3f2fd' },
                    inRange: {
                        color: ['#1565c0', '#1976d2', '#2196f3', '#42a5f5', '#64b5f6']
                    }
                },
                series: [{
                    name: '定价热力图',
                    type: 'heatmap',
                    data: data,
                    label: {
                        show: true,
                        color: '#fff',
                        fontSize: 10,
                        formatter: function(params) {
                            return '$' + params.data[2];
                        }
                    },
                    emphasis: {
                        itemStyle: {
                            shadowBlur: 10,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    }
                }]
            };

            chart.setOption(option);
            charts.multiDimensional = chart;
        }

        static initEfficiencyChart() {
            const container = document.getElementById('efficiencyChart');
            if (!container) return;

            const chart = echarts.init(container);
            const data = DataGenerator.generateEfficiencyData();

            const option = {
                tooltip: {
                    trigger: 'axis',
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    borderColor: '#64b5f6',
                    textStyle: { color: '#fff' }
                },
                legend: {
                    data: ['定价效率', '激增倍数'],
                    textStyle: { color: '#e3f2fd' },
                    top: '5%'
                },
                grid: {
                    left: '10%',
                    right: '10%',
                    top: '20%',
                    bottom: '15%'
                },
                xAxis: {
                    type: 'category',
                    data: data.map(d => d.hour + ':00'),
                    axisLabel: { color: '#e3f2fd', fontSize: 10 },
                    axisLine: { lineStyle: { color: '#64b5f6' } }
                },
                yAxis: [
                    {
                        type: 'value',
                        name: '效率(%)',
                        nameTextStyle: { color: '#e3f2fd' },
                        axisLabel: { color: '#e3f2fd', fontSize: 10 },
                        axisLine: { lineStyle: { color: '#64b5f6' } },
                        splitLine: { lineStyle: { color: 'rgba(255, 255, 255, 0.1)' } }
                    },
                    {
                        type: 'value',
                        name: '倍数',
                        nameTextStyle: { color: '#e3f2fd' },
                        axisLabel: { color: '#e3f2fd', fontSize: 10 },
                        axisLine: { lineStyle: { color: '#42a5f5' } }
                    }
                ],
                series: [
                    {
                        name: '定价效率',
                        type: 'line',
                        data: data.map(d => d.efficiency),
                        smooth: true,
                        lineStyle: { color: '#64b5f6', width: 3 },
                        itemStyle: { color: '#64b5f6' },
                        areaStyle: {
                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                { offset: 0, color: 'rgba(100, 181, 246, 0.3)' },
                                { offset: 1, color: 'rgba(100, 181, 246, 0.1)' }
                            ])
                        }
                    },
                    {
                        name: '激增倍数',
                        type: 'line',
                        yAxisIndex: 1,
                        data: data.map(d => d.surge),
                        smooth: true,
                        lineStyle: { color: '#42a5f5', width: 2 },
                        itemStyle: { color: '#42a5f5' }
                    }
                ]
            };

            chart.setOption(option);
            charts.efficiency = chart;
        }

        static initConditionalChart() {
            const container = document.getElementById('conditionalChart');
            if (!container) return;

            const chart = echarts.init(container);
            const data = DataGenerator.generateConditionalData();

            const option = {
                tooltip: {
                    trigger: 'item',
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    borderColor: '#64b5f6',
                    textStyle: { color: '#fff' },
                    formatter: '{b}: ${c} ({d}%)'
                },
                legend: {
                    orient: 'vertical',
                    left: 'left',
                    top: 'center',
                    textStyle: { color: '#e3f2fd', fontSize: 11 }
                },
                series: [{
                    name: '条件定价',
                    type: 'pie',
                    radius: ['40%', '70%'],
                    center: ['65%', '50%'],
                    avoidLabelOverlap: false,
                    itemStyle: {
                        borderRadius: 5,
                        borderColor: '#fff',
                        borderWidth: 2
                    },
                    label: {
                        show: false,
                        position: 'center'
                    },
                    emphasis: {
                        label: {
                            show: true,
                            fontSize: '14',
                            fontWeight: 'bold',
                            color: '#fff'
                        },
                        itemStyle: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    },
                    labelLine: { show: false },
                    data: data.map((item, index) => ({
                        value: item.value,
                        name: item.name,
                        itemStyle: {
                            color: ['#64b5f6', '#42a5f5', '#2196f3', '#1976d2', '#1565c0'][index]
                        }
                    }))
                }]
            };

            chart.setOption(option);
            charts.conditional = chart;
        }

        static initTimeWindowChart() {
            const container = document.getElementById('timeWindowChart');
            if (!container) return;

            const chart = echarts.init(container);
            const data = DataGenerator.generateTimeWindowData();

            const option = {
                tooltip: {
                    trigger: 'axis',
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    borderColor: '#64b5f6',
                    textStyle: { color: '#fff' }
                },
                legend: {
                    data: ['小时窗口', '时段窗口', '日类型窗口'],
                    textStyle: { color: '#e3f2fd', fontSize: 10 },
                    top: '5%'
                },
                grid: {
                    left: '10%',
                    right: '10%',
                    top: '25%',
                    bottom: '15%'
                },
                xAxis: {
                    type: 'category',
                    data: data.map(d => d.period),
                    axisLabel: {
                        color: '#e3f2fd',
                        fontSize: 9,
                        rotate: 45
                    },
                    axisLine: { lineStyle: { color: '#64b5f6' } }
                },
                yAxis: {
                    type: 'value',
                    axisLabel: { color: '#e3f2fd', fontSize: 10 },
                    axisLine: { lineStyle: { color: '#64b5f6' } },
                    splitLine: { lineStyle: { color: 'rgba(255, 255, 255, 0.1)' } }
                },
                series: [
                    {
                        name: '小时窗口',
                        type: 'bar',
                        data: data.map(d => d.hourWindow),
                        itemStyle: { color: '#64b5f6' }
                    },
                    {
                        name: '时段窗口',
                        type: 'bar',
                        data: data.map(d => d.periodWindow),
                        itemStyle: { color: '#42a5f5' }
                    },
                    {
                        name: '日类型窗口',
                        type: 'bar',
                        data: data.map(d => d.dayTypeWindow),
                        itemStyle: { color: '#2196f3' }
                    }
                ]
            };

            chart.setOption(option);
            charts.timeWindow = chart;
        }

        static initHierarchicalChart() {
            const container = document.getElementById('hierarchicalChart');
            if (!container) return;

            const chart = echarts.init(container);
            const data = DataGenerator.generateHierarchicalData();

            const option = {
                tooltip: {
                    trigger: 'item',
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    borderColor: '#64b5f6',
                    textStyle: { color: '#fff' }
                },
                series: [{
                    type: 'funnel',
                    left: '10%',
                    top: '10%',
                    width: '80%',
                    height: '80%',
                    min: 0,
                    max: 100,
                    minSize: '0%',
                    maxSize: '100%',
                    sort: 'descending',
                    gap: 2,
                    label: {
                        show: true,
                        position: 'inside',
                        color: '#fff',
                        fontSize: 12,
                        formatter: '{b}: {c}%'
                    },
                    labelLine: {
                        length: 10,
                        lineStyle: { width: 1, type: 'solid' }
                    },
                    itemStyle: {
                        borderColor: '#fff',
                        borderWidth: 1
                    },
                    emphasis: {
                        label: { fontSize: 14 }
                    },
                    data: data
                }]
            };

            chart.setOption(option);
            charts.hierarchical = chart;
        }

        static initNestedChart() {
            const container = document.getElementById('nestedChart');
            if (!container) return;

            const chart = echarts.init(container);
            const data = DataGenerator.generateNestedData();

            const option = {
                tooltip: {
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    borderColor: '#64b5f6',
                    textStyle: { color: '#fff' }
                },
                radar: {
                    indicator: [
                        { name: '记录数量', max: 2000 },
                        { name: '平均费用', max: 40 },
                        { name: '定价效率', max: 100 }
                    ],
                    shape: 'circle',
                    splitNumber: 5,
                    axisName: {
                        color: '#e3f2fd',
                        fontSize: 12
                    },
                    splitLine: {
                        lineStyle: { color: 'rgba(255, 255, 255, 0.2)' }
                    },
                    splitArea: {
                        show: true,
                        areaStyle: {
                            color: ['rgba(100, 181, 246, 0.1)', 'rgba(100, 181, 246, 0.05)']
                        }
                    },
                    axisLine: {
                        lineStyle: { color: 'rgba(255, 255, 255, 0.3)' }
                    }
                },
                series: [{
                    name: '嵌套聚合',
                    type: 'radar',
                    data: [
                        {
                            value: [data.route.count, data.route.avgFare, data.route.efficiency],
                            name: '路线层级',
                            itemStyle: { color: '#64b5f6' },
                            areaStyle: { color: 'rgba(100, 181, 246, 0.3)' }
                        },
                        {
                            value: [data.timeCustomer.count, data.timeCustomer.avgFare, data.timeCustomer.efficiency],
                            name: '时间客户层级',
                            itemStyle: { color: '#42a5f5' },
                            areaStyle: { color: 'rgba(66, 165, 245, 0.3)' }
                        },
                        {
                            value: [data.pricing.count, data.pricing.avgFare, data.pricing.efficiency],
                            name: '定价层级',
                            itemStyle: { color: '#2196f3' },
                            areaStyle: { color: 'rgba(33, 150, 243, 0.3)' }
                        }
                    ]
                }],
                legend: {
                    data: ['路线层级', '时间客户层级', '定价层级'],
                    textStyle: { color: '#e3f2fd' },
                    bottom: '5%'
                }
            };

            chart.setOption(option);
            charts.nested = chart;
        }
    }

    // 统计数据更新器
    class StatsUpdater {
        static updateStats() {
            const stats = {
                avgFare: (Math.random() * 15 + 15).toFixed(2),
                avgTipRate: (Math.random() * 10 + 15).toFixed(1),
                surgeMultiplier: (Math.random() * 0.5 + 1.2).toFixed(2),
                efficiency: (Math.random() * 15 + 80).toFixed(1)
            };

            this.animateValue('avgFare', '$' + stats.avgFare);
            this.animateValue('avgTipRate', stats.avgTipRate + '%');
            this.animateValue('surgeMultiplier', stats.surgeMultiplier + 'x');
            this.animateValue('efficiency', stats.efficiency + '%');
        }

        static animateValue(elementId, targetValue) {
            const element = document.getElementById(elementId);
            if (!element) return;

            element.style.transform = 'scale(1.1)';
            element.style.transition = 'all 0.3s ease';

            setTimeout(() => {
                element.textContent = targetValue;
                element.style.transform = 'scale(1)';
            }, 150);
        }
    }

    // 响应式处理器
    class ResponsiveHandler {
        static handleResize() {
            Object.values(charts).forEach(chart => {
                if (chart && typeof chart.resize === 'function') {
                    chart.resize();
                }
            });
        }

        static init() {
            window.addEventListener('resize', this.handleResize);
        }
    }

    // 主初始化函数
    function initDashboard() {
        try {
            // 清除加载状态
            document.querySelectorAll('.loading').forEach(loader => {
                loader.style.display = 'none';
            });

            // 初始化所有图表
            ChartInitializer.initMultiDimensionalChart();
            ChartInitializer.initEfficiencyChart();
            ChartInitializer.initConditionalChart();
            ChartInitializer.initTimeWindowChart();
            ChartInitializer.initHierarchicalChart();
            ChartInitializer.initNestedChart();

            // 更新统计数据
            StatsUpdater.updateStats();

            // 设置定时更新
            setInterval(() => {
                StatsUpdater.updateStats();
            }, 5000);

            // 初始化响应式处理
            ResponsiveHandler.init();

            console.log('仪表板初始化完成');
        } catch (error) {
            console.error('仪表板初始化失败:', error);
        }
    }

    // 页面加载完成后初始化
    document.addEventListener('DOMContentLoaded', function() {
        setTimeout(initDashboard, 500);
    });

    // 页面卸载时清理资源
    window.addEventListener('beforeunload', function() {
        Object.values(charts).forEach(chart => {
            if (chart && typeof chart.dispose === 'function') {
                chart.dispose();
            }
        });
        if (animationId) {
            cancelAnimationFrame(animationId);
        }
    });
</script>
</body>
</html>
